<?php
/**
 * Created by PhpStorm.
 * User: 丶晓
 * Date: 2017/8/11
 * Time: 10:08
 */

namespace app\common\wechat;


class WechatSDK // 速用公众号
{
    const QRCODE_TYPE_TEMP = 1;
    const QRCODE_TYPE_LIMIT = 2;
    const QRCODE_TYPE_LIMIT_STR = 3;
    private $_appid;
    private $_appsecret;
    /**
     * 定义模版
     */
    private $_msg_template = array(
        'text' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>',//文本回复XML模板
        'image' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[%s]]></MediaId></Image></xml>',//图片回复XML模板
        'music' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>',//音乐模板
        'news' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>%s</ArticleCount><Articles>%s</Articles></xml>',// 新闻主体
        'news_item' => '<item><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>',//某个新闻模板
    );

    public function __construct($id, $secret)
    {
        $this->_appid = $id;
        $this->_appsecret = $secret;
    }

    /**
     * 设置菜单
     */
    public function menuSet($menu)
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $this->getAccessToken();
        $data = $menu;
        $result = $this->_requestPost($url, $data);
        $result_obj = json_decode($result);
        if ($result_obj->errmsg == 'ok') {
            return $result_obj;
        } else {
            echo $result_obj->errmsg, '<br>';
            return false;
        }
    }

    /**
     * 获取 access_tonken
     * @param string $token_file 用来存储token的临时文件
     */
    public function getAccessToken($token_file = './access_token')
    {
        // 考虑过期问题，将获取的access_token存储到某个文件中
        $life_time = 7200;
        if (file_exists($token_file) && time() - filemtime($token_file) < $life_time) {
            // 存在有效的access_token
            return file_get_contents($token_file);
        }
        // 目标URL：
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->_appid}&secret={$this->_appsecret}";
        //向该URL，发送GET请求
        $result = $this->_requestGet($url);
        if (!$result) {
            return false;
        }
        // 存在返回响应结果
        $result_obj = json_decode($result);
        $token_file = './access_token';
        // 写入,需要调配linux的etc目录下的文件
        //file_put_contents($token_file,$result_obj->access_token);
        return isset($result_obj->access_token) ?$result_obj->access_token:null;
    }

    /**
     * 发送GET请求的方法
     * @param string $url URL
     * @param bool $ssl 是否为https协议
     * @return string 响应主体Content
     */
    public function _requestGet($url, $ssl = true)
    {
        // curl完成
        $curl = curl_init();

        //设置curl选项
        curl_setopt($curl, CURLOPT_URL, $url);//URL
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36';
        curl_setopt($curl, CURLOPT_USERAGENT, $user_agent);//user_agent，请求代理信息
        curl_setopt($curl, CURLOPT_AUTOREFERER, true);//referer头，请求来源
        //SSL相关
        if ($ssl) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//禁用后cURL将终止从服务端进行验证
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);//检查服务器SSL证书中是否存在一个公用名(common name)。
        }
        curl_setopt($curl, CURLOPT_HEADER, false);//是否处理响应头
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//curl_exec()是否返回响应结果

        // 发出请求
        $response = curl_exec($curl);
        if (false === $response) {
            return false;
        }
        return $response;
    }

    /**
     * 发送post请求
     * @param string $url URL
     * @param bool $ssl 是否为https协议
     * @return string 响应主体Content
     */
    public function _requestPost($url, $data, $ssl = true)
    {
        // curl完成
        $curl = curl_init();

        //设置curl选项
        curl_setopt($curl, CURLOPT_URL, $url);//URL
        $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36';
        curl_setopt($curl, CURLOPT_USERAGENT, $user_agent);//user_agent，请求代理信息
        curl_setopt($curl, CURLOPT_AUTOREFERER, true);//referer头，请求来源
        //SSL相关
        if ($ssl) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//禁用后cURL将终止从服务端进行验证
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);//检查服务器SSL证书中是否存在一个公用名(common name)。
        }
        // 处理post相关选项
        curl_setopt($curl, CURLOPT_POST, true);// 是否为POST请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);// 处理请求数据
        // 处理响应结果
        curl_setopt($curl, CURLOPT_HEADER, false);//是否处理响应头
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//curl_exec()是否返回响应结果

        // 发出请求
        $response = curl_exec($curl);
        if (false === $response) {
            return false;
        }
        return $response;
    }

    public function getmenu()
    {

        $url = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=" . $this->getAccessToken();
        $data = $this->_requestGet($url);

        return $data;
    }

    /**
     * 菜单删除
     */
    public function menuDelete()
    {
        $url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=' . $this->getAccessToken();
        $result = $this->_requestGet($url);
        $result_obj = json_decode($result);
        if ($result_obj->errcode == 0) {
            return true;
        } else {
            return false;
        }
    }

    public function responseMsg()
    {

        // 获取请求时POST：XML字符串
        // $_POST,不是key/value型因此不能使用该数组
        $xml_str = $GLOBALS['HTTP_RAW_POST_DATA'];

        // 如果没有post数据，则响应空字符串表示结束
        if (empty($xml_str)) {
            die ('');
        }
        // 解析该xml字符串，利用simpleXML
        libxml_disable_entity_loader(true);//禁止xml实体解析，防止xml注入
        $request_xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);//从字符串获取simpleXML对象

        // 判断该消息的类型通过元素：MsgType
        switch ($request_xml->MsgType) {

            case 'event'://事件消息
                // 判断具体的事件类型（关注，取消，点击）
                $event = $request_xml->Event;
                //关注事件
                if ($event == 'subscribe') {
                    $this->_doSubscribe($request_xml);
                } elseif ($event == 'CLICK') {

                    $eventkey = $request_xml->EventKey;
                    if ($eventkey == 'rselfmenu_0_0') {
                        $content = '欢迎你关注速用科技，专注小程序制作第一平台，我们会尽快完善平台功能！谢谢！';
                        $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $content);
                    } //elseif($eventkey == )
                }
                break;

            case 'text': // 文本消息
                $this->_doText($request_xml);
                break;

        }
    }

    /**
     * 用于处理关注事件的方法
     * @param  [type] $request_xml 事件信息对象
     * @return [type]              [description]
     */
    private function _doSubscribe($request_xml)
    {

        $response_content = '欢迎你关注速用科技，专注小程序制作第一平台，我们会尽快完善平台功能！谢谢！';
        $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content);
    }

    /**
     * 发送文本信息
     * @param  [type] $to      目标用户ID
     * @param  [type] $from    来源用户ID
     * @param  [type] $content 内容
     * @return [type]          [description]
     */
    private function _msgText($to, $from, $content)
    {
        $response = sprintf($this->_msg_template['text'], $to, $from, time(), $content);
        echo $response;
    }

    /**
     * 用于处理文本消息的方法
     */
    private function _doText($request_xml)
    {
        //新建一个mysql对象;
        $mysql = new Mysql();

        // 获取文本内容
        $content = trim($request_xml->Content);
        // 对内容进行判断
        //因为这个菜单访问量比较大，所以我并没有存入数据库，
        if ('0' == $content) {
            // 显示帮助信息
            $response_content = '亲爱的hr你好，由于设置二级菜单需要认证，认证需要400元';
            // 将处理好的响应数据回复给用户
            $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content);
        } elseif ('看看新闻' == $content || '7' == $content) {
            //查询新闻表
            $sql = "select * from newsImages order by ids desc limit 4";
            $res = $mysql->execute_dql2($sql);
            $item_list = array(
                array('title' => $res[3][title], 'desc' => $res[3]['description'], 'picurl' => $res[3]['picUrl'], 'url' => $res[3]['url']),
                array('title' => $res[2][title], 'desc' => $res[2]['description'], 'picurl' => $res[2]['picUrl'], 'url' => $res[2]['url']),
                array('title' => $res[1]['title'], 'desc' => $res[1]['description'], 'picurl' => $res[1]['picUrl'], 'url' => $res[1]['url']),
                array('title' => $res[0]['title'], 'desc' => $res[0]['description'], 'picurl' => $res[0]['picUrl'], 'url' => $res[0]['url']),
            );

            $this->_msgNews($request_xml->FromUserName, $request_xml->ToUserName, $item_list);
        }
    }

    /**
     * 回复图文消息
     */
    private function _msgNews($to, $from, $item_list = array())
    {
        // 拼凑文章部分
        $item_str = '';
        foreach ($item_list as $item) {
            $item_str .= sprintf($this->_msg_template['news_item'], $item['title'], $item['desc'], $item['picurl'], $item['url']);
        }
        //拼凑整体图文部分
        $response = sprintf($this->_msg_template['news'], $to, $from, time(), count($item_list), $item_str);
        die($response);
    }

    /**
     * [getQRCodeTicket description]
     * @param $content 内容
     * @param $type qr码类型
     * @param $expire 有效期，如果是临时的类型则需要该参数
     * @return string ticket
     */
    public function getQRCodeTicket($content = '', $strType = 'scene_str', $type = 'QR_STR_SCENE', $expire = 2592000)
    {
        $access_token = $this->getAccessToken();
        //目标地址
        $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $access_token;
        //生成$data
        $data_arr['expire_seconds'] = $expire;
        $data_arr['action_name'] = $type;
        $data_arr['action_info']['scene'][$strType] = $content;
        $data = json_encode($data_arr);
        //发送post请求
        $result = $this->_requestPost($url, $data);
        $result_obj = json_decode($result);
        if (!$result_obj) {
            return false;
        }
        return isset($result_obj->ticket)?$result_obj->ticket:null;
    }

    /**
     * 根据ticket获取二维码
     */
    public function getQRCode($ticket, $isIMG = false)
    {
        //对ticket进行加密
        $ticket = urlencode($ticket);
        //填写url
        $url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . $ticket;
        //发送请求
        return $isIMG ? $this->_requestGet($url) : $url;
    }
}